package com.geek.monitor;

import com.geek.monitor.event.HookEvent;
import com.geek.monitor.event.HookMouseEvent;
import com.geek.monitor.handler.MouseEventHandler;
import com.sun.jna.Structure;
import com.sun.jna.examples.win32.Kernel32;
import com.sun.jna.examples.win32.User32;
import com.sun.jna.examples.win32.User32.HHOOK;
import com.sun.jna.examples.win32.User32.HOOKPROC;
import com.sun.jna.examples.win32.User32.MSG;
import com.sun.jna.examples.win32.W32API.HMODULE;
import com.sun.jna.examples.win32.W32API.LRESULT;
import com.sun.jna.examples.win32.W32API.WPARAM;

/**
 * 监听鼠标
 */
public class MouseHook implements Runnable{

	private static HHOOK hhk;
	private static HOOKPROC mouseHook;
	final static User32 lib = User32.INSTANCE;
	private boolean [] on_off=null;

	private MouseEventHandler handler;

	public MouseHook(boolean [] on_off){
		this.on_off = on_off;
	}
	public MouseHook(boolean [] on_off, MouseEventHandler handler){
		this.on_off = on_off;
		this.handler = handler;
	}

	public void addEventHandler(MouseEventHandler handler) {
		this.handler = handler;
	}

	public interface LowLevelMouseProc extends HOOKPROC {
		LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);
	}

	public static class MOUSEHOOKSTRUCT extends Structure {
		public static class ByReference extends MOUSEHOOKSTRUCT implements
				Structure.ByReference {
		};
		public User32.POINT pt;
		public int wHitTestCode;
		public User32.ULONG_PTR dwExtraInfo;
	}

	public void run() {
		HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
		mouseHook = new HOOKPROC() {
			public LRESULT callback(int nCode, WPARAM wParam,
			                        MOUSEHOOKSTRUCT info) {
				if (!on_off[0]) {
					System.exit(0);
				}
				if (nCode >= 0) {
					if(handler != null){
						HookEvent event = new HookMouseEvent(wParam.intValue());
						handler.handle(event);
					}else{
						System.out.println("没有相应的鼠标消息处理器");
					}
				}
				return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
			}
		};
		hhk = lib.SetWindowsHookEx(User32.WH_MOUSE_LL, mouseHook, hMod, 0);
		int result;
		MSG msg = new MSG();
		while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
			if (result == -1) {
				System.err.println("error in get message");
				break;
			} else {
				System.err.println("got message");
				lib.TranslateMessage(msg);
				lib.DispatchMessage(msg);
			}
		}
		lib.UnhookWindowsHookEx(hhk);
	}

}